import asyncio
import uvicorn
from fastapi import FastAPI, WebSocket, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from starlette.websockets import WebSocketDisconnect
import json
from typing import Dict, Any

from service_manager import ServiceManager
from config_manager import get_config

# 初始化服务管理器
service_manager = ServiceManager()

# 获取各个管理器
db_manager = service_manager.get_database_manager()
file_monitor_manager = service_manager.get_file_monitor_manager()
websocket_manager = service_manager.get_websocket_manager()

# 使用服务管理器的生命周期上下文
lifespan = service_manager.lifespan_context

# 创建FastAPI应用
app = FastAPI(
    title="订单管理系统服务端",
    description="提供订单管理和文件监控服务",
    version="1.0.0",
    lifespan=lifespan
)

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/")
async def root():
    """根路径"""
    return {
        "message": "订单管理系统服务端",
        "version": "1.0.0",
        "status": "running"
    }

@app.get("/status")
async def get_status():
    """获取服务状态"""
    return service_manager.get_service_status()

@app.post("/start-monitoring")
async def start_monitoring(data: dict):
    """开始文件监控"""
    try:
        base_path = data.get("base_path")
        date = data.get("date")
        
        if not base_path or not date:
            return {"success": False, "message": "缺少必要参数"}
        
        success = file_monitor_manager.start_monitoring(base_path, date)
        
        if success:
            # 通知所有客户端
            await websocket_manager.broadcast_monitoring_started(base_path, date)
            return {"success": True, "message": "监控启动成功"}
        else:
            return {"success": False, "message": "监控启动失败"}
        
    except Exception as e:
        return {"success": False, "message": f"启动监控时发生错误: {str(e)}"}

@app.post("/stop-monitoring")
async def stop_monitoring():
    """停止文件监控"""
    try:
        success = file_monitor_manager.stop_monitoring()
        
        if success:
            # 通知所有客户端
            await websocket_manager.broadcast_monitoring_stopped()
            return {"success": True, "message": "监控已停止"}
        else:
            return {"success": False, "message": "停止监控失败"}
        
    except Exception as e:
        return {"success": False, "message": f"停止监控时发生错误: {str(e)}"}

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """WebSocket端点"""
    await websocket.accept()
    websocket_manager.add_connection(websocket)
    
    try:
        # 发送初始数据
        print("📤 正在发送初始数据...")
        await websocket_manager.send_initial_data(websocket)
        print("✅ 初始数据发送完成")
        
        # 心跳任务
        async def heartbeat():
            """发送心跳保持连接"""
            while True:
                try:
                    await asyncio.sleep(30)  # 每30秒发送一次心跳
                    await websocket.send_json({"type": "ping"})
                    print("💓 发送心跳")
                except WebSocketDisconnect:
                    print("👋 客户端断开连接（心跳任务）")
                    break
                except Exception as e:
                    print(f"❌ 心跳发送失败: {e}")
                    break
        
        # 启动心跳任务
        heartbeat_task = asyncio.create_task(heartbeat())
        
        try:
            while True:
                try:
                    # 接收客户端消息，设置60秒超时
                    print("📥 等待客户端消息...")
                    data = await asyncio.wait_for(
                        websocket.receive_text(), 
                        timeout=60.0
                    )
                    print(f"📨 收到消息: {data}")
                    
                    message = json.loads(data)
                    print(f"📋 解析消息类型: {message.get('type', 'unknown')}")
                    
                    # 处理消息
                    await websocket_manager.handle_message(message, websocket)
                    print("✅ 消息处理完成")
                    
                except WebSocketDisconnect:
                    # 客户端正常断开连接
                    print("👋 客户端断开连接")
                    break
                except asyncio.TimeoutError:
                    # 超时，发送心跳
                    print("⏱️ 接收超时，发送心跳")
                    try:
                        await websocket.send_json({"type": "ping"})
                        print("✅ 心跳发送成功")
                    except (WebSocketDisconnect, Exception) as e:
                        if isinstance(e, WebSocketDisconnect):
                            print("👋 客户端断开连接（心跳时）")
                        else:
                            print(f"❌ 心跳发送失败: {e}")
                        break
                except json.JSONDecodeError as e:
                    print(f"❌ JSON解析错误: {e}")
                    print(f"📄 原始数据: {data}")
                    try:
                        await websocket_manager._send_error(websocket, f'JSON解析错误: {str(e)}')
                    except WebSocketDisconnect:
                        print("👋 客户端断开连接（发送错误消息时）")
                        break
                except Exception as e:
                    print(f"❌ 处理消息时发生错误: {e}")
                    import traceback
                    traceback.print_exc()
                    # 检查是否是连接断开相关的错误
                    if isinstance(e, WebSocketDisconnect):
                        print("👋 客户端断开连接")
                        break
                    # 尝试发送错误消息，但如果连接已断开则忽略
                    try:
                        await websocket_manager._send_error(websocket, f'处理消息时发生错误: {str(e)}')
                    except (WebSocketDisconnect, Exception):
                        break
        finally:
            # 取消心跳任务
            heartbeat_task.cancel()
            try:
                await heartbeat_task
            except asyncio.CancelledError:
                pass
            
    except WebSocketDisconnect:
        # 客户端正常断开连接，不需要打印错误
        print("👋 WebSocket连接已断开")
    except Exception as e:
        error_type = type(e).__name__
        error_code = getattr(e, 'code', 'unknown')
        
        # 对于websockets库的异常，提取错误码
        if hasattr(e, 'code'):
            error_code = e.code
        elif hasattr(e, 'close_code'):
            error_code = e.close_code
        
        print(f"❌ WebSocket处理错误: {error_type} - {e} (代码: {error_code})")
        
        # 如果是连接关闭错误，不打印详细信息
        if error_code in [1000, 1001, 1012] or "connection closed" in str(e).lower():
            if error_code == 1012:
                print("✅ 服务器重启，客户端连接关闭")
            else:
                print("✅ 客户端正常断开连接")
        else:
            print(f"❌ WebSocket异常详情: {e}")
            import traceback
            traceback.print_exc()
    finally:
        websocket_manager.remove_connection(websocket)

# 添加REST API端点
@app.get("/orders")
async def get_orders(date: str = None):
    """获取所有订单"""
    return db_manager.get_all_orders(date)

@app.get("/orders/{order_number}")
async def get_order(order_number: str, date: str = None):
    """获取指定订单"""
    order = db_manager.get_order_by_number(order_number, date)
    if not order:
        raise HTTPException(status_code=404, detail="订单不存在")
    return order

@app.post("/orders")
async def create_order(order_data: dict, date: str = None):
    """创建订单"""
    order = db_manager.create_order(order_data, date)
    return order

@app.put("/orders/{order_number}")
async def update_order(order_number: str, order_data: dict, date: str = None):
    """更新订单"""
    order = db_manager.update_order(order_number, order_data, date)
    if not order:
        raise HTTPException(status_code=404, detail="订单不存在")
    return order

@app.delete("/orders/{order_number}")
async def delete_order(order_number: str, date: str = None):
    """删除订单"""
    success = db_manager.delete_order(order_number, date)
    if not success:
        raise HTTPException(status_code=404, detail="订单不存在")
    return {"message": "订单删除成功"}

@app.get("/orders/search/{keyword}")
async def search_orders(keyword: str, date: str = None):
    """搜索订单"""
    return db_manager.search_orders(keyword, date)

@app.get("/statistics")
async def get_statistics(date: str = None):
    """获取统计信息"""
    return db_manager.get_statistics(date)

@app.get("/dates")
async def get_all_dates():
    """获取所有日期表"""
    return {"dates": db_manager.get_all_dates()}

@app.get("/table-info")
async def get_table_info(date: str = None):
    """获取指定日期表的信息"""
    return db_manager.get_table_info(date)

@app.post("/cleanup")
async def cleanup_old_tables(keep_days: int = 30):
    """清理旧表"""
    db_manager.delete_old_tables(keep_days)
    return {"message": f"已清理超过{keep_days}天的旧表"}

@app.post("/migrate")
async def migrate_database():
    """迁移数据库，添加新字段"""
    try:
        db_manager.migrate_existing_tables()
        return {"message": "数据库迁移完成"}
    except Exception as e:
        return {"message": f"数据库迁移失败: {str(e)}"}

@app.post("/restart-monitoring")
async def restart_monitoring():
    """重启监控"""
    success = service_manager.restart_monitoring()
    if success:
        return {"success": True, "message": "监控重启成功"}
    else:
        return {"success": False, "message": "监控重启失败"}

@app.post("/full-scan")
async def full_scan():
    """全量扫描当前日期目录"""
    try:
        print(f"🔍 开始全量扫描，扫描当前日期目录")
        results = service_manager.full_scan_current_date()
        
        return {
            "success": True, 
            "message": "全量扫描完成",
            "results": results
        }
    except Exception as e:
        return {
            "success": False, 
            "message": f"全量扫描失败: {str(e)}"
        }

@app.post("/cleanup-missing-orders")
async def cleanup_missing_orders():
    """清理不存在的订单"""
    try:
        print("🧹 开始清理无效订单...")
        results = service_manager.cleanup_missing_orders()
        
        return {
            "success": True, 
            "message": "清理完成",
            "results": results
        }
    except Exception as e:
        return {
            "success": False, 
            "message": f"清理失败: {str(e)}"
        }



if __name__ == "__main__":
    import sys
    
    # 检测是否为生产环境（PyInstaller打包）
    is_production = getattr(sys, 'frozen', False)
    
    print("🚀 启动订单管理系统服务端...")
    if is_production:
        print("🔧 运行环境: 生产环境（PyInstaller打包）")
    else:
        print("🔧 运行环境: 开发环境")
    
    # 从配置文件读取服务器配置
    config = get_config()
    server_config = config.get_server_config()
    
    # 生产环境强制禁用 debug 和 reload
    if is_production:
        server_config['debug'] = False
        print("⚠️ 生产环境：已强制禁用 debug 模式")
    
    print(f"📋 服务器配置: {server_config}")
    print(f"WebSocket地址: ws://{server_config['host']}:{server_config['port']}/ws")
    print(f"HTTP API地址: http://{server_config['host']}:{server_config['port']}")
    
    # 生产环境始终使用 app 对象，不使用字符串（避免导入问题）
    if server_config['debug'] and not is_production:
        # 开发环境：使用字符串和 reload
        print("🔄 开发模式：启用自动重载")
        uvicorn.run(
            "main:app",
            host=server_config['host'],
            port=server_config['port'],
            reload=True,
            log_level="info"
        )
    else:
        # 生产环境：使用 app 对象，禁用 reload
        print("🚀 生产模式：禁用自动重载")
        uvicorn.run(
            app,
            host=server_config['host'],
            port=server_config['port'],
            reload=False,
            log_level="info"
        )
